package com.aiyige.page.login.model.impl;

import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.aiyige.BuildConfig;
import com.aiyige.MyApp;
import com.aiyige.R;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.BaseActivity;
import com.aiyige.base.api.ApiHelper;
import com.aiyige.base.api.ApiManager;
import com.aiyige.base.api.JsonUtil;
import com.aiyige.base.api.ResponseCode;
import com.aiyige.base.api.TokenManager;
import com.aiyige.base.eventbus.EventGprsNotificationConfigChange;
import com.aiyige.base.eventbus.EventLogin;
import com.aiyige.base.eventbus.EventLogout;
import com.aiyige.base.eventbus.EventNimLogin;
import com.aiyige.im.ImCache;
import com.aiyige.im.RecentContactHelper;
import com.aiyige.im.SessionHelper;
import com.aiyige.jpush.TagAliasOperatorHelper;
import com.aiyige.logic.user.UserDataManager;
import com.aiyige.model.Oauth2Login;
import com.aiyige.model.ServiceACCIDModel;
import com.aiyige.model.User;
import com.aiyige.model.request.GetServiceACCIDListRequest;
import com.aiyige.model.request.GetUserTodoTasks;
import com.aiyige.model.request.LoginOtherRequest;
import com.aiyige.model.response.ErrorResponse;
import com.aiyige.page.login.LoginPage;
import com.aiyige.page.login.callbacks.ILoginCallBack;
import com.aiyige.page.login.model.ILoginModel;
import com.aiyige.page.login.view.ILoginView;
import com.aiyige.page.my.message.util.MessageUtil;
import com.aiyige.page.my.settings.ConfigUltis;
import com.aiyige.utils.AccountUtil;
import com.aiyige.utils.DummyDataUtil;
import com.aiyige.utils.ListUtil;
import com.aiyige.utils.ShareUtil;
import com.aiyige.utils.ToastX;
import com.aiyige.utils.prefs.Prefs;
import com.aiyige.utils.removal.RemovalHandler;
import com.aiyige.utils.removal.WuDaoPrefsHelper;
import com.alibaba.android.arouter.launcher.ARouter;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.AbortableFuture;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.auth.LoginInfo;
import com.umeng.socialize.UMAuthListener;
import com.umeng.socialize.UMShareAPI;
import com.umeng.socialize.bean.SHARE_MEDIA;
import com.vondear.rxtools.RxActivityTool;
import com.vondear.rxtools.RxEncodeTool;
import com.vondear.rxtools.RxTool;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import cn.jpush.android.api.JPushInterface;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * 登录实现层
 * Created by xiachao on 17/8/10.
 */

public class LoginManager implements ILoginModel {

    private boolean isLogin = false;

    public static final String TAG = LoginManager.class.getSimpleName();
    private static LoginManager mInstance;

    private Set<ILoginCallBack> callBackList = new HashSet<ILoginCallBack>();


    private ILoginCallBack loginCallBack;

    ILoginView mView;


    public List<ServiceACCIDModel> getServiceList() {
        return serviceList;
    }

    public void setServiceList(List<ServiceACCIDModel> serviceList) {
        this.serviceList = serviceList;
    }

    private List<ServiceACCIDModel> serviceList;

    public ILoginCallBack getLoginCallBack() {
        return loginCallBack;
    }

    public void setLoginCallBack(ILoginCallBack loginCallBack) {
        this.loginCallBack = loginCallBack;
    }

    /**
     * 在发送状态时不允许remove回调，否则会报错
     */
    private boolean isSendStatus;

    /**
     * 登录管理 <BR>
     *
     * @return
     */
    public static synchronized LoginManager getInstance() {
        if (mInstance == null) {
            mInstance = new LoginManager();
        }
        return mInstance;
    }

    /**
     * 添加回调<BR>
     *
     * @param currentCallBack
     * @return
     */
    public boolean addLoginCallBack(ILoginCallBack currentCallBack) {
        return callBackList.add(currentCallBack);
    }

    /**
     * 外部无需监听回调时销毁callback
     *
     * @param callBack
     */
    public void removeLoginCallBack(ILoginCallBack callBack) {
        if (isSendStatus) {
            return;
        }
        if (callBackList == null) {
            return;
        }
        callBackList.remove(callBack);
    }

    /**
     * [清空当前回调]<BR>
     *
     * @param callBack
     */
    public void removeAllCallBack(ILoginCallBack callBack) {
        if (callBackList != null) {
            callBackList.clear();
        }
    }

    /**
     * 发送登录成功回调<BR>
     * [功能详细描述]
     */
    public void sendLoginSuccessCallBack(User user) {
        // 在发送状态
        isSendStatus = true;
        Iterator<ILoginCallBack> list = callBackList.iterator();
        while (list.hasNext()) {
            list.next().success(user);
        }
        if (getLoginCallBack() != null) {
            getLoginCallBack().success(user);
        }
        // 取消发送状态
        isSendStatus = false;
    }

    /**
     * 发送登录失败回调<BR>
     * [功能详细描述]
     */
    public void sendLoginFaildCallBack(String errorCode) {
        // 在发送状态
        isSendStatus = true;
        Iterator<ILoginCallBack> list = callBackList.iterator();
        while (list.hasNext()) {
            list.next().error(errorCode);
        }
        if (getLoginCallBack() != null) {
            getLoginCallBack().error(errorCode);
        }
        // 取消发送状态
        isSendStatus = false;
    }


    private Prefs getPrefs() {
        return MyApp.getInstance().getPrefs();
    }

    /**
     * 是否已经登录 <BR>
     *
     * @return
     */
    public static boolean isLogin() {
        return AccountUtil.isLogin();
    }

    /**
     * 是否 已经登录，如果未登录则自动跳转至登录页面 <BR>
     *
     * @param needGoToLogin true如果未登录则自动跳转登录
     * @return
     */
    public boolean isLogin(boolean needGoToLogin) {
        boolean isLogin = isLogin();
        if (!isLogin && needGoToLogin) {
            ARouter.getInstance().build(ARouterConfig.LoginPage).navigation();
        }
        return isLogin;
    }

    /**
     * 跳转登录页面 <BR>
     */
    public void startLoginActivity(Activity activity) {
        // 弹出单独的登录页面
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setClass(MyApp.getInstance(), LoginPage.class);
        MyApp.getInstance().startActivity(intent);
    }

    /**
     * 跳转登录页面 <BR>
     */
    public void startLoginActivity() {
        // 弹出单独的登录页面
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setClass(MyApp.getInstance(), LoginPage.class);
        MyApp.getInstance().startActivity(intent);
    }

    /**
     * 云信logou
     * 退出登录
     */
    public void logout(boolean notifyServer) {
        String clientInfo;
        try {
            clientInfo = Base64.encodeToString((BuildConfig.AIYIGE_CLIENT_ID + ":" + BuildConfig.AIYIGE_CLIENT_SECRET).getBytes("UTF-8"), Base64.NO_WRAP | Base64.URL_SAFE);
        } catch (Exception e) {
            clientInfo = "";
        }
        if (notifyServer) {
            TokenManager.getService().oauth2Logout("Basic " + clientInfo, "Basic " + clientInfo, AccountUtil.getCurrentUser().getAccessToken().access_token).enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(final Call<ResponseBody> call, final Response<ResponseBody> response) {
                    try {
                        if (response.isSuccessful()) {

                        }
                    } catch (Exception e) {
                        ApiHelper.getInstance().failed(this, call, response, e.getMessage());
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {

                }
            });
        }
        // 云信logou
        NimUIKit.logout();
//        NIMClient.toggleNotification(false);// 其他地方已经做了限制
        DropManager.getInstance().destroy();
        ImCache.clear();

        AccountUtil.setNimLogin(false);
        RecentContactHelper.getInstance().cleanRecentContactList();
        AccountUtil.clearCurrentUser();
        MessageUtil.clearNewMessage();
        TagAliasOperatorHelper.getInstance().cleanLoginTagAndAlias(MyApp.getAppContext());
        EventBus.getDefault().post(new EventLogout());
        SessionHelper.otherImLogoutCallback();
    }

    public void logout() {
        logout(true);
    }


    /**
     * 账号密码登录
     *
     * @param userName
     * @param passWord
     * @param iLoginCallBack
     */
    @Override
    public void login(String userName, String passWord, final ILoginCallBack iLoginCallBack) {
        mView.showLoading();
        ApiManager.getService().oauth2Login(new Oauth2Login(userName, RxTool.Md5(passWord))).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(final Call<ResponseBody> call, final Response<ResponseBody> response) {
                mView.hideLoading();
                try {
                    if (response.isSuccessful()) {
                        User user = JsonUtil.toObject(response.body().string(), User.class);
                        user = new User(user);
                        AccountUtil.updateCurrentUser(user);
                        TagAliasOperatorHelper.getInstance().registerLoginTagAndAlias(MyApp.getAppContext(), user);
                        doLoginSomething();
                        iLoginCallBack.success(user);
                    } else {
                        ErrorResponse data = JsonUtil.toObject(response.errorBody().string(), ErrorResponse.class);
//                        onFailure(call, new Throwable(data.getMessage()));
                        iLoginCallBack.error(data.getMessage());
                    }
                } catch (Exception e) {
                    ApiHelper.getInstance().failed(this, call, response, e.getMessage());
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                mView.hideLoading();
                if (t != null && !TextUtils.isEmpty(t.getMessage())) {
                    ToastX.show(t.getMessage());
                }
            }
        });
    }

    /**
     * 给三方登录专用
     *
     * @param baseActivity
     * @param request
     * @param iLoginCallBack
     */
    private void doLoginThird(final BaseActivity baseActivity, final User request, final ILoginCallBack iLoginCallBack) {
        baseActivity.showLoading();
        ApiManager.getService().oauth2ThirdLogin(request).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(final Call<ResponseBody> call, final Response<ResponseBody> response) {
                try {
                    mView.hideLoading();
                } catch (Exception e) {

                }
                try {
                    if (response.isSuccessful()) {
                        User user = JsonUtil.toObject(response.body().string(), User.class);
//                        // 如果没有绑定手机号，需要绑定手机号
//                        if (user != null && TextUtils.isEmpty(user.getMobile())) {
//                            ARouter.getInstance().build(ARouterConfig.BindingPhonePage).withString("userId",user.getId()).navigation();
//                            return;
//                        }
                        user = new User(user);
                        AccountUtil.updateCurrentUser(user);
                        TagAliasOperatorHelper.getInstance().registerLoginTagAndAlias(MyApp.getAppContext(), user);
                        doLoginSomething();
                        iLoginCallBack.success(user);
                    } else {
                        ErrorResponse data = JsonUtil.toObject(response.errorBody().string(), ErrorResponse.class);
//                        onFailure(call, new Throwable(data.getMessage()));
                        if (data != null && data.getCode().equals(ResponseCode.BIND_MOBILE_FIRST)) {// 如果这个第三方账号没有绑定过手机号，需要先绑定手机号
                            // 如果没有绑定手机号，需要绑定手机号
                            User.ThirdOauthBackup thirdOauthBackup = request.getThirdOauthBackup();
                            ARouter.getInstance().build(ARouterConfig.BindingPhonePage).withParcelable("thirdOauthBackup",thirdOauthBackup).navigation();
                        } else {
                            iLoginCallBack.error(data != null ?data.getMessage():null);
                        }
                    }
                } catch (Exception e) {
                    ApiHelper.getInstance().failed(this, call, response, e.getMessage());
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                if (iLoginCallBack != null) {
                    iLoginCallBack.error(t != null ? t.getMessage() : null);
                }
                baseActivity.hideLoading();
            }
        });
    }


    /**
     * 用户手动登录后需要做的事情
     */
    private void doLoginSomething() {
        RemovalHandler.getInstance().doRemoval();
        UserDataManager.getInstance().requestUserTodoTasks(GetUserTodoTasks.TYPE_LOGIN,null);
    }


    /**
     * App 启动后需要做的事情
     */
    public void onStartAppDoSomething() {
        getServiceACCIDList(null);

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 设置配置是否已经迁移
                boolean settingConfigRemoval = MyApp.getInstance().getPrefs().getBoolean("settingConfigRemoval",false);
                if (!settingConfigRemoval) {
                    Prefs prefs = new WuDaoPrefsHelper(MyApp.getAppContext()).getPrefs();
                    // 通知 是否接受uxiaoxi推送开关
                    boolean enable_notification = prefs.getBoolean("enable_notification",true);
                    ConfigUltis.setMessagePushEnable(enable_notification);
                    if (enable_notification) {
                        JPushInterface.resumePush(MyApp.getAppContext());
                    } else {
                        JPushInterface.stopPush(MyApp.getAppContext());
                    }
                    NIMClient.toggleNotification(enable_notification);

                    // 2G/3G/4G播放、缓存、上传提醒 开关
                    boolean wifi_data_remind = prefs.getBoolean("wifi_data_remind",true);
                    ConfigUltis.setGprsNotificationEnable(wifi_data_remind);
                    EventBus.getDefault().post(new EventGprsNotificationConfigChange(wifi_data_remind));
                    MyApp.getInstance().getPrefs().getBoolean("settingConfigRemoval",true);
                }
            }
        }).start();
    }


    public void getServiceACCIDList(final Handler handler) {
        String json = MyApp.getInstance().getPrefs().getString("ServiceACCIDModel", null);
        if (!TextUtils.isEmpty(json)) {
            List<ServiceACCIDModel> list = JsonUtil.toObjectList(json, ServiceACCIDModel.class);
            if (!ListUtil.isEmpty(list)) {
                setServiceList(list);
                return;
            }
        }
        GetServiceACCIDListRequest.newBuilder().build().enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful()) {
                    try {
                        String json = response.body().string();
                        Log.v("", json);
                        List<ServiceACCIDModel> list = JsonUtil.toObjectList(json, ServiceACCIDModel.class);
                        if (!ListUtil.isEmpty(list)) {
                            setServiceList(list);
                            MyApp.getInstance().getPrefs().putString("ServiceACCIDModel", json);
                            if (handler != null) {
                                handler.sendEmptyMessage(0);
                            }
                        } else {
                            if (handler != null) {
                                handler.sendEmptyMessage(0);
                            }
                        }
                    } catch (IOException e) {
                        if (handler != null) {
                            handler.sendEmptyMessage(0);
                        }
                    }
                } else {
                    if (handler != null) {
                        handler.sendEmptyMessage(0);
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                if (handler != null) {
                    handler.sendEmptyMessage(0);
                }
            }
        });
    }


    @Override
    public void setView(ILoginView view) {
        this.mView = view;
    }


    /**
     * 第三方登录
     *
     * @param activity
     * @param platform 平台
     */
    @Override
    public void loginByOther(final BaseActivity activity, SHARE_MEDIA platform) {
        if (platform.name().contains("WEIXIN") && !ShareUtil.isWeixinAvilible()) {
            ToastX.show(MyApp.getAppContext().getString(R.string.weixin_not_install));
            return;
        }

//        UMShareConfig config = new UMShareConfig();
//        config.isNeedAuthOnGetUserInfo(true);
        UMShareAPI mShareAPI = UMShareAPI.get(activity);
//        mShareAPI.setShareConfig(config);
        mShareAPI.getPlatformInfo(activity, platform, new UMAuthListener() {
            @Override
            public void onStart(SHARE_MEDIA share_media) {

            }


            @Override
            public void onComplete(SHARE_MEDIA share_media, int i, Map<String, String> map) {
                String source = "";
                int type = 0;
                if (share_media == SHARE_MEDIA.WEIXIN) {
                    type = 3;
                    source = "weixin";
                } else if (share_media == SHARE_MEDIA.QQ) {
                    type = 1;
                    source = "qq";
                } else if (share_media == SHARE_MEDIA.SINA) {
                    type = 2;
                    source = "sina";
                }
//                for (Map.Entry<String, String> entry : map.entrySet()) {
//                    if (!TextUtils.isEmpty(entry.getValue())) {
//                        entry.setValue();
//                    }
//                }
                LoginOtherRequest loginOtherRequest = LoginOtherRequest.newBuilder()
                        .accessToken(map.get(type == 2 ? "accessToken" : "access_token"))
                        .avatar(map.get("iconurl"))
                        .nickName(RxEncodeTool.base64Encode2String(map.get("name").getBytes(Charset.forName("UTF-8"))))
                        .openid(map.get("openid"))
                        .province(map.get("province"))
                        .sex(map.get("gender"))
                        .type(type)
                        .uid(map.get("uid"))
                        .city(map.get(type == 2 ? "location" : "city"))
                        .country(map.get("country"))
                        .build();
                User user = new User();
                User.ThirdOauthBackup thirdOauthBackup = new User.ThirdOauthBackup();
                thirdOauthBackup.setAccessToken(loginOtherRequest.getAccessToken());
                thirdOauthBackup.setAvatar(loginOtherRequest.getAvatar());
                thirdOauthBackup.setOpenid(loginOtherRequest.getOpenid());
                thirdOauthBackup.setSource(source);
                thirdOauthBackup.setUid(loginOtherRequest.getUid());
                thirdOauthBackup.setNickName(loginOtherRequest.getNickName());
                user.setThirdOauthBackup(thirdOauthBackup);

                User.MoreBackup moreBackup = new User.MoreBackup();
                moreBackup.setCity(DummyDataUtil.getCityId(loginOtherRequest.getProvince(), loginOtherRequest.getCity()));
                String sex = "x";
                if (!TextUtils.isEmpty(loginOtherRequest.getSex()) && loginOtherRequest.getSex().equals("男")) {
                    sex = "m";
                } else if (!TextUtils.isEmpty(loginOtherRequest.getSex()) && loginOtherRequest.getSex().equals("女")) {
                    sex = "f";
                }
                moreBackup.setSex(sex);
                user.setMoreBackup(moreBackup);
                Log.i("xcLogin", loginOtherRequest.toString());
                doLoginThird(activity, user, new ILoginCallBack() {
                    @Override
                    public void success(User user) {
                        ToastX.show(MyApp.getInstance().getString(R.string.login_success));
                        //SessionUtil.updateCurrentSession(session);
                        EventBus.getDefault().post(new EventLogin(user));
                        RxActivityTool.finishActivity(activity.getClass());
                    }

                    @Override
                    public void error(String errorCode) {
                        if (!TextUtils.isEmpty(errorCode)) {
                            if (errorCode.equals("0") || errorCode.equals("2")) {
                                return;
                            }
//                            ToastX.show(errorCode);
                        }
                    }
                });
            }

            @Override
            public void onError(SHARE_MEDIA share_media, int i, Throwable throwable) {

                ToastX.show(throwable.getMessage());
            }

            @Override
            public void onCancel(SHARE_MEDIA share_media, int i) {
                ToastX.show(MyApp.getAppContext().getString(R.string.authorization_failed_please_try_again));
            }
        });
    }

    public boolean checkBindingPhone() {
        User user = AccountUtil.getCurrentUser();
        if (user != null && TextUtils.isEmpty(user.getMobile())) {
            ARouter.getInstance().build(ARouterConfig.BindingPhonePage).navigation();
            return false;
        } else {
            return true;
        }
    }

    public void IMLogin() {
        if (AccountUtil.getLoginInfo() == null) {
            return;
        }
        try {
            AbortableFuture loginRequest = NimUIKit.login(AccountUtil.getLoginInfo(), new RequestCallback<LoginInfo>() {
                @Override
                public void onSuccess(LoginInfo param) {
                    LogUtil.i(TAG, "doLoginThird success");
                    if (BuildConfig.DEBUG) {
                        ToastX.show("IM 登录成功");
                    }
                    boolean enableMessagePush = ConfigUltis.isEnableMessagePush();
                    NIMClient.toggleNotification(enableMessagePush);
                    AccountUtil.setNimLogin(true);
                    EventBus.getDefault().post(new EventNimLogin());
                    SessionHelper.otherImLoginCallback();
//                onLoginDone();

//                DemoCache.setAccount(account);
//                saveLoginInfo(account, token);
//
//                // 初始化消息提醒配置
//                initNotificationConfig();
//
//                // 进入主界面
//                MainActivity.start(LoginActivity.this, null);
//                finish();
                }

                @Override
                public void onFailed(int code) {
//                onLoginDone();
                    if (code == 302 || code == 404) {
//                        ToastX.show("登录失败: " + code);
                    } else {
//                        ToastX.show("登录失败: " + code);
                    }
                }

                @Override
                public void onException(Throwable exception) {
                    LogUtil.i(TAG, "debug: IM 登录异常" + exception.toString());
                    if (BuildConfig.DEBUG) {
//                        ToastX.show("debug: IM 登录异常：" + exception.toString());
                    }
//                Toast.makeText(LoginActivity.this, R.string.login_exception, Toast.LENGTH_LONG).show();
//                onLoginDone();
                }
            });
        } catch (Exception e) {

        }


    }

}
